package com.ruoyi.AI.service.impl;

import cn.hutool.http.Header;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.AI.domain.*;
import com.ruoyi.AI.entity.*;
import com.ruoyi.AI.mapper.ExecuteMapper;
import com.ruoyi.AI.service.ChartGPTService;
import com.ruoyi.AI.service.ConstValuePool;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.file.JsonToExcelConverter;
import com.ruoyi.tcp.server.WebSocketServerHandler;
import lombok.val;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;

import javax.annotation.Resource;
import java.io.FileOutputStream;
import java.util.*;
import java.util.concurrent.Semaphore;


@Service("chartGPTService")
public class ChartGPTServiceImpl implements ChartGPTService {

    @Value("${Coze.variables.apiKey}")
    private String apiKeyCoze;
    @Value("${Coze.variables.maxTokens}")
    private String maxTokensCoze;
    @Value("${Coze.variables.model}")
    private String modelCoze;
    @Value("${Coze.variables.temperature}")
    private String temperatureCoze;
    @Value("${Coze.variables.url}")
    private String urlCoze;

    @Resource
    MessagesLogsServiceImpl messagesLogsService;

    @Resource
    ExecuteMapper executeMapper;
    private WebSocketServerHandler nettyServerHandler =new WebSocketServerHandler();


    @Override
    public String sendFluxCoze(String uid,String prompt) throws InterruptedException {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        JSONObject bodyJson = new JSONObject();
        ArrayList<MessageCoze> messages = new ArrayList<>();

        //获取聊天记录
        MessagesLogs messagesLogsReq=new MessagesLogs();
        messagesLogsReq.setDelFlag(0L);
        messagesLogsReq.setUserId(loginUser.getUserId().toString());
        val messagesLogs = messagesLogsService.selectMessagesLogsList(messagesLogsReq);
        messagesLogs.stream().forEach(e->{
            MessageCoze message2 = new MessageCoze();
            message2.setContent(e.getContent());
            message2.setContent_type("answer");
            if(e.getRole().equals("assistant")){
                message2.setType("answer");
            }
            message2.setRole(e.getRole());
            messages.add(message2);
        });

        MessagesLogs messagesLogsSave=new MessagesLogs();
        messagesLogsSave.setUserId(loginUser.getUserId().toString());
        messagesLogsSave.setContent(prompt);
        messagesLogsSave.setRole("user");
        messagesLogsSave.setCreateTime(new Date());
        messagesLogsService.insertMessagesLogs(messagesLogsSave);

        bodyJson.put("chat_history", messages);
        bodyJson.put("bot_id", modelCoze);
        bodyJson.put("stream", true);
        bodyJson.put("query",prompt);
        bodyJson.put("conversation_id", loginUser.getUserId().toString());
        bodyJson.put("user", loginUser.getUserId().toString());

        //这里用流式请求

        Flux<String> chatResponseFlux = ConstValuePool.PROXY_OPENAI_CLIENT
//                .defaultHeader()
//                .head("Authorization", "Bearer pat_aBDN3fbG7tWxkYiJrRlhVvFE1CjSFP7xC57tOwTGexaup7Naggm8prbMHUN76NiW" )
                .post()
                .uri(urlCoze)
                .header("Authorization", "Bearer "+apiKeyCoze)
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(bodyJson)
                .retrieve()
                .bodyToFlux(String.class);// 得到string返回，便于查看结束标志

        StringBuilder resultBuilder = new StringBuilder();
        // 设置同步信号量
        Semaphore semaphore = new Semaphore(0);
        chatResponseFlux.subscribe(
                value -> {

                    try {
                        ChatResponseCoze chatResponse = JSONUtil.toBean(value, ChatResponseCoze.class);
                        if(chatResponse.getEvent().equals("message")){
                            if(chatResponse.getMessage().getType().equals("function_call")){
                                MessageCoze delta = chatResponse.getMessage();
                                String res = delta.getContent();
                                if (res != null) {
                                    String jsonString = res;
                                    JSONObject jsonObject = new JSONObject(jsonString);

                                    // 获取 "name" 的值
                                    String plugin_name = jsonObject.getStr("plugin_name");

                                    nettyServerHandler.sendMsg(null, uid + "&" +"正在使用："+ plugin_name);

                                }
                            }

                            if(chatResponse.getMessage().getType().equals("tool_response")){
                                MessageCoze delta = chatResponse.getMessage();
                                String res = delta.getContent();
                                if (res != null) {
                                    nettyServerHandler.sendMsg(null, uid + "&" +"正在分析数据...");

                                }
                            }

                            if(chatResponse.getMessage().getType().equals("answer")&&!chatResponse.getMessage().getContent_type().equals("card")){
                                MessageCoze delta = chatResponse.getMessage();
                                String res = delta.getContent();
                                if (res != null) {
                                    resultBuilder.append(res);
                                    nettyServerHandler.sendMsg(null, uid + "&" + resultBuilder.toString());

                                }
                            }
                        }
                        else if(chatResponse.getEvent().equals("done")){
                            return;
                        }


                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }, // 获得数据，拼接结果，发送给前端
                error -> {
                    semaphore.release();
                    throw new RuntimeException("chatpgt执行出错",error);
                }, // 失败释放信号量，并报错
                semaphore::release// 成功释放信号量
        );
        semaphore.acquire();
        String ResMsg = resultBuilder.toString();

        MessagesLogs messagesLogsSave2=new MessagesLogs();
        messagesLogsSave2.setUserId(loginUser.getUserId().toString());
        messagesLogsSave2.setContent(ResMsg);
        messagesLogsSave2.setRole("assistant");
        messagesLogsSave2.setCreateTime(new Date());
        messagesLogsService.insertMessagesLogs(messagesLogsSave2);

        return ResMsg;

    }



}
